package com.dms.modules.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dms.common.exception.BusinessException;
import com.dms.modules.product.entity.Product;
import com.dms.modules.product.entity.ProductCategory;
import com.dms.modules.product.mapper.ProductCategoryMapper;
import com.dms.modules.product.mapper.ProductMapper;
import com.dms.modules.product.service.ProductCategoryService;
import com.dms.modules.product.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商品分类服务实现类
 */
@Slf4j
@Service
public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMapper, ProductCategory> implements ProductCategoryService {

    @Lazy
    @Autowired
    private ProductService productService;

    @Autowired
    private ProductMapper productMapper;

    @Override
    public List<ProductCategory> getCategoryList(Long parentId) {
        LambdaQueryWrapper<ProductCategory> wrapper = new LambdaQueryWrapper<>();
        if (parentId != null) {
            wrapper.eq(ProductCategory::getParentId, parentId);
        } else {
            wrapper.eq(ProductCategory::getParentId, 0L);
        }
        wrapper.eq(ProductCategory::getShowStatus, 1)
               .eq(ProductCategory::getDeleted, 0)
               .orderByAsc(ProductCategory::getSort);
        return list(wrapper);
    }

    @Override
    public List<ProductCategory> getCategoryTree() {
        // 获取所有分类
        List<ProductCategory> allCategories = this.list();
        if (allCategories == null || allCategories.isEmpty()) {
            return Collections.emptyList();
        }

        // 构建树形结构
        // 1. 找出所有一级分类
        List<ProductCategory> rootCategories = allCategories.stream()
                .filter(category -> category.getParentId() == 0)
                .collect(Collectors.toList());

        // 2. 为一级分类设置子分类
        rootCategories.forEach(root -> {
            root.setChildren(getChildCategories(root.getId(), allCategories));
        });

        return rootCategories;
    }

    @Override
    public List<ProductCategory> getChildren(Long parentId) {
        LambdaQueryWrapper<ProductCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductCategory::getParentId, parentId)
               .eq(ProductCategory::getVisible, 1)
               .orderByAsc(ProductCategory::getSort);
        return list(wrapper);
    }

    @Override
    public List<ProductCategory> getDimensionCategories(String dimension) {
        LambdaQueryWrapper<ProductCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductCategory::getDimension, dimension)
               .eq(ProductCategory::getShowStatus, 1)
               .eq(ProductCategory::getDeleted, 0)
               .orderByAsc(ProductCategory::getSort);
        return list(wrapper);
    }

    @Override
    public List<Long> getCategoryAndChildrenIds(Long categoryId) {
        List<Long> ids = new ArrayList<>();
        ids.add(categoryId);
        
        // 递归获取所有子分类ID
        getChildrenIds(categoryId, ids);
        
        return ids;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addCategory(ProductCategory category) {
        // 设置分类层级
        if (category.getParentId() == 0) {
            category.setLevel(1);
        } else {
            ProductCategory parent = getById(category.getParentId());
            if (parent == null) {
                throw new BusinessException("父分类不存在");
            }
            category.setLevel(parent.getLevel() + 1);
        }
        
        category.setCreateTime(LocalDateTime.now());
        category.setUpdateTime(LocalDateTime.now());
        
        if (!save(category)) {
            throw new BusinessException("添加分类失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCategory(ProductCategory category) {
        ProductCategory existingCategory = getById(category.getId());
        if (existingCategory == null) {
            throw new BusinessException("分类不存在");
        }
        
        category.setUpdateTime(LocalDateTime.now());
        if (!updateById(category)) {
            throw new BusinessException("更新分类失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteCategory(Long categoryId) {
        // 检查是否有子分类
        if (count(new LambdaQueryWrapper<ProductCategory>()
                .eq(ProductCategory::getParentId, categoryId)) > 0) {
            throw new BusinessException("存在子分类，无法删除");
        }
        
        if (!removeById(categoryId)) {
            throw new BusinessException("删除分类失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateVisible(Long categoryId, Integer visible) {
        ProductCategory category = getById(categoryId);
        if (category == null) {
            throw new BusinessException("分类不存在");
        }
        
        category.setVisible(visible);
        category.setUpdateTime(LocalDateTime.now());
        
        if (!updateById(category)) {
            throw new BusinessException("更新分类显示状态失败");
        }
    }

    @Override
    public IPage<Product> getCategoryProducts(Long categoryId, Integer pageNum, Integer pageSize) {
        log.debug("开始获取分类商品列表: categoryId={}, pageNum={}, pageSize={}", categoryId, pageNum, pageSize);
        
        // 检查分类是否存在
        ProductCategory category = getById(categoryId);
        if (category == null) {
            log.warn("分类不存在: categoryId={}", categoryId);
            throw new BusinessException("分类不存在");
        }

        // 获取分类及其子分类的ID列表
        List<Long> categoryIds = getCategoryAndChildrenIds(categoryId);
        log.debug("获取到分类及子分类ID列表: {}", categoryIds);

        // 构建查询条件
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Product::getCategoryId, categoryIds)
                .eq(Product::getStatus, 1)  // 上架状态
                .eq(Product::getDeleted, 0) // 未删除
                .orderByDesc(Product::getCreateTime);

        // 执行分页查询
        Page<Product> page = new Page<>(pageNum, pageSize);
        IPage<Product> result = productService.page(page, wrapper);
        
        log.debug("分类商品列表查询完成: total={}, current={}, size={}", 
                result.getTotal(), result.getCurrent(), result.getSize());
        
        return result;
    }

    @Override
    public List<ProductCategory> getCategoriesByDimension(String dimension) {
        return list(new LambdaQueryWrapper<ProductCategory>()
            .eq(ProductCategory::getDimension, dimension)
            .eq(ProductCategory::getVisible, 1)
            .orderByAsc(ProductCategory::getSort));
    }

    @Override
    public IPage<Product> getFilteredCategoryProducts(List<Long> categoryIds, Integer pageNum, Integer pageSize) {
        log.debug("开始获取多级分类筛选商品列表: categoryIds={}, pageNum={}, pageSize={}", categoryIds, pageNum, pageSize);
        
        if (categoryIds == null || categoryIds.isEmpty()) {
            throw new BusinessException("分类ID列表不能为空");
        }

        // 验证分类的层级关系
        validateCategoryHierarchy(categoryIds);
        
        // 获取当前选中的分类ID
        Long currentCategoryId = categoryIds.get(categoryIds.size() - 1);
        ProductCategory currentCategory = getById(currentCategoryId);
        
        // 构建查询条件
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        
        // 如果是父级分类，获取该分类及其所有子分类的商品
        if (currentCategory.getLevel() < 3) {  // 假设最多三级分类
            List<Long> allCategoryIds = getCategoryAndChildrenIds(currentCategoryId);
            wrapper.in(Product::getCategoryId, allCategoryIds);
        } else {
            // 如果是最后一级分类，只获取该分类的商品
            wrapper.eq(Product::getCategoryId, currentCategoryId);
        }
        
        wrapper.eq(Product::getStatus, 1)  // 上架状态
               .eq(Product::getDeleted, 0) // 未删除
               .orderByDesc(Product::getCreateTime);

        // 执行分页查询
        Page<Product> page = new Page<>(pageNum, pageSize);
        IPage<Product> result = productService.page(page, wrapper);
        
        log.debug("多级分类筛选商品列表查询完成: total={}, current={}, size={}", 
                result.getTotal(), result.getCurrent(), result.getSize());
        
        return result;
    }

    /**
     * 验证分类的层级关系
     */
    private void validateCategoryHierarchy(List<Long> categoryIds) {
        for (int i = 0; i < categoryIds.size(); i++) {
            ProductCategory category = getById(categoryIds.get(i));
            if (category == null) {
                throw new BusinessException("分类不存在: " + categoryIds.get(i));
            }
            
            // 验证父子关系
            if (i > 0) {
                if (!category.getParentId().equals(categoryIds.get(i - 1))) {
                    throw new BusinessException("分类层级关系不正确");
                }
            }
        }
    }

    /**
     * 递归获取子分类ID
     */
    private void getChildrenIds(Long categoryId, List<Long> ids) {
        List<ProductCategory> children = getChildren(categoryId);
        for (ProductCategory child : children) {
            ids.add(child.getId());
            getChildrenIds(child.getId(), ids);
        }
    }

    /**
     * 构建分类树
     */
    private List<ProductCategory> buildTree(List<ProductCategory> categories) {
        // 按父ID分组
        Map<Long, List<ProductCategory>> parentMap = categories.stream()
            .collect(Collectors.groupingBy(ProductCategory::getParentId));
            
        // 设置子分类
        categories.forEach(category -> 
            category.setChildren(parentMap.getOrDefault(category.getId(), new ArrayList<>())));
            
        // 返回顶级分类
        return parentMap.getOrDefault(0L, new ArrayList<>());
    }

    /**
     * 递归获取子分类
     *
     * @param parentId 父分类ID
     * @param allCategories 所有分类列表
     * @return 子分类列表（包含层级结构）
     */
    private List<ProductCategory> getChildCategories(Long parentId, List<ProductCategory> allCategories) {
        List<ProductCategory> children = allCategories.stream()
                .filter(category -> parentId.equals(category.getParentId()))
                .collect(Collectors.toList());
        
        children.forEach(child -> {
            child.setChildren(getChildCategories(child.getId(), allCategories));
        });
        
        return children;
    }
    
    /**
     * 递归获取所有子分类ID
     *
     * @param parentId 父分类ID
     * @param categoryIds 存储所有分类ID的列表
     */
    private void getAllChildCategoryIds(Long parentId, List<Long> categoryIds) {
        LambdaQueryWrapper<ProductCategory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProductCategory::getParentId, parentId);
        List<ProductCategory> children = this.list(queryWrapper);
        
        if (children != null && !children.isEmpty()) {
            for (ProductCategory child : children) {
                categoryIds.add(child.getId());
                getAllChildCategoryIds(child.getId(), categoryIds);
            }
        }
    }

    @Override
    public Page<ProductCategory> pageCategories(Integer pageNum, Integer pageSize, String name) {
        Page<ProductCategory> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<ProductCategory> queryWrapper = new LambdaQueryWrapper<>();
        
        // 如果提供了名称，按名称过滤
        if (StringUtils.hasText(name)) {
            queryWrapper.like(ProductCategory::getName, name);
        }
        
        // 按排序和ID排序
        queryWrapper.orderByAsc(ProductCategory::getSort).orderByAsc(ProductCategory::getId);
        
        return this.page(page, queryWrapper);
    }

    @Override
    public boolean hasProducts(Long categoryId) {
        if (categoryId == null) {
            return false;
        }
        
        // 获取所有子分类ID（包括当前分类）
        List<Long> categoryIds = new ArrayList<>();
        categoryIds.add(categoryId);
        getAllChildCategoryIds(categoryId, categoryIds);
        
        // 查询这些分类下是否有商品
        return productMapper.existsByCategoryIds(categoryIds);
    }
} 